/**
 * 客户端向服务端发起的心跳
 */
package cn.com.klun.netty.client;

import cn.com.klun.build.TaskBuildSource;
import cn.com.klun.cache.QuartzConstants;
import cn.com.klun.cache.QuartzPropertiesCache;
import cn.com.klun.cache.QuartzTaskConfigCache;
import cn.com.klun.netty.NettyMessage;
import cn.com.klun.netty.ServerIpAndPortSet;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;

/**
 * @author chenmin-ds 客户端向服务端发起的心跳
 */
public class NettyClientHeartBeatHandler extends ChannelInboundHandlerAdapter {

	private Logger logger = LoggerFactory.getLogger("NettyClientHeartBeatHandler");

	private TaskBuildSource taskBuildSourceProxy;
	
	public NettyClientHeartBeatHandler(TaskBuildSource taskBuildSourceProxy){
		this.taskBuildSourceProxy = taskBuildSourceProxy;
	}
	/**
	 * 空闲时发送一条消息到服务端
	 */
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		try {
			Channel channel = NettyClientStartup.getInstance().getChannel();
			NettyMessage nettyMessage = new NettyMessage(QuartzConstants.BUSINESS_TYPE_XT);
			nettyMessage.setJsonObject("BUSINESS_CODE", QuartzPropertiesCache.getBusinessCode());
			channel.writeAndFlush(nettyMessage).addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
			new NettyClientTaskRunLogSend().sendInfoServer();
		} catch (Exception e) {
			logger.error("空闲时向发服务端发送心跳信息异常", e);
		}
	}

	

	/**
	 * 通道激活时触发，当客户端connect成功后，服务端就会接收到这个事件，从而可以把客户端的Channel记录下来，供后面复用 :连接上服务端时会被调用
	 */
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		super.channelActive(ctx);
		logger.info("连接上服务端，可以进行业务处理了。" + ctx.channel().toString());
	}
	
	
	/**
	 * 出错是会触发，做一些错误处理 :服务端不可调用的时间触发
	 */
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.info("exceptionCaught:{}",cause);
		ctx.close();
	}
	
	@SuppressWarnings("rawtypes")
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		try {
			logger.info("服务端不可调用的时间触发重新连接。。。。。。");
			
			//当与服务端断开联接的时候清理掉全局性唯一任务 2017-09-22 陈民
			ConcurrentMap<String, JSONObject> map = QuartzTaskConfigCache.getTaskInfoList();
			Iterator iterator = map.entrySet().iterator();
			JSONObject json = null;
			while(iterator.hasNext()){
				json = (JSONObject) ((Entry) iterator.next()).getValue();
				if(json.getInt("fullTaskCount") == 1){
					taskBuildSourceProxy.oneTask(json,"false");
					logger.info("当与服务端断开联接的时候清理掉全局性唯一任务：{}",json.toString());
				}
			}
			
			ServerIpAndPortSet.setIpPort();
			NettyClientStartup.getInstance().doConnect();
		} catch (Exception e) {
			logger.error("exceptionCaught,出错是会触发，做一些错误处理,重新建立连接", e);
		}
	}
	
}
